Active Record Basics Guide Refresh, Encrypted Attributes Re-Optimization, and more... | This Week in Rails
本文がサンプルコードを含めてたくさん変更されています
ActiveRecordに関する変更です
このプルリクエストの作者は、自身のRailsアプリケーションをrailsのmainブランチで動かしてみたらテストコードの実行におよそ5倍の時間が掛かるようになったため、原因を調べてこのプルリクエストを出したそうです
どこに原因があったのか、プルリクエストで説明されています
RailsにおけるModelの特定の属性を暗号化するための仕組みを提供するクラスです
このクラスに key_provider というメソッドがあります
もともと、この key_provider メソッドは、インスタンス変数をつかってメモ化されていました
このプルリクエストでは、そのインスタンス変数が意図しないタイミングで上書きされる場合があることを指摘して、メモ化の処理をなくす変更をしています
その変更が原因で、テストの実行に時間がかかるケースが発生するようになっていました
具体的にはModelの属性に対して、keyを明示的に渡す、あるいは、決定論的にkey_providerを宣言する場合です この場合には、属性を読み込むたびにkey_providerをインスタンス化するためのキーを導出する必要があります
結果的に ActiveSupport::KeyGenerator#generate_key と OpenSSL::KDF.pbkdf2_hmac を何度も呼び出すことになり、大きなオーバーヘッドが発生します
今回のプルリクエストでは、属性に対してkeyを明示的に渡す場合、属性のkey_providerを決定論的に宣言する場合、について、それぞれインスタンス変数を使ってメモ化の処理を実装することで、オーバーヘッドを小さくし、処理の高速化を実現しています
ActiveRecordに関する変更です
タイトル和訳は「MySQL 8.0.19 では、INSERT INTO ... ON DUPLICATE KEY UPDATE ステートメントの VALUES 句と SET 句にエイリアスが導入されています」
このプルリクエストではMySQL 8.0.0 ~ 8.0.18の場合に発生するエラーを修正しています
ただし、今回のプルリクエストの前までは、その処理に入る条件は「MySQL 8.0.0以上」となっていました
code:rb
if !mariadb? && database_version >= "8.0.0"
values_alias = quote_table_name("#{insert.model.table_name}_values")
MySQLにおいてこのステートメントでVALUESのエイリアスを使用できるのは8.0.19以降であるため、今回のプルリクエストでは該当の処理に入る条件を「MySQL 8.0.19以上」に修正しています